package by.gamedev.site.client.app.place;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.place.shared.PlaceChangeEvent;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.ui.HasConstrainedValue;

/**
 * Drives a {@link ValueChangeHandler} populated with {@link ProxyListPlace} instances, keeping it in sync with the {@link PlaceController}'s notion
 * of the current place, and firing place change events as selections are made.
 */
public class ProxyListPlacePicker implements ValueChangeHandler<ProxyListPlace>, PlaceChangeEvent.Handler {

    HasConstrainedValue<ProxyListPlace> view;

    private final PlaceController       placeController;
    private final ProxyPlaceToListPlace proxyPlaceToListPlace;

    public ProxyListPlacePicker(final PlaceController placeController, final ProxyPlaceToListPlace proxyPlaceToListPlace) {
        this.placeController = placeController;
        this.proxyPlaceToListPlace = proxyPlaceToListPlace;
    }

    @Override
    public void onPlaceChange(final PlaceChangeEvent event) {
        view.setValue(proxyPlaceToListPlace.proxyListPlaceFor(event.getNewPlace()), false);
    }

    @Override
    public void onValueChange(final ValueChangeEvent<ProxyListPlace> event) {
        placeController.goTo(event.getValue());
    }

    public HandlerRegistration register(final EventBus eventBus, final HasConstrainedValue<ProxyListPlace> viewValue) {

        view = viewValue;

        final HandlerRegistration placeRegistration = eventBus.addHandler(PlaceChangeEvent.TYPE, this);

        final HandlerRegistration viewRegistration = viewValue.addValueChangeHandler(this);

        return new HandlerRegistration() {
            @Override
            public void removeHandler() {
                placeRegistration.removeHandler();
                viewRegistration.removeHandler();
                view = null;
            }
        };
    }
}
